package com.boodaba.todocarts.test.app;

import static com.boodaba.todocarts.test.app.IdenticalLabelMatcher.aLabelIdenticalWith;

import org.jmock.Expectations;
import org.junit.runner.RunWith;

import com.boodaba.todocarts.app.ILabelEditActivity;
import com.boodaba.todocarts.app.LabelEditPresenter;
import com.boodaba.todocarts.domain.ILabelRepository;
import com.boodaba.todocarts.domain.Label;

import static com.googlecode.instinct.expect.Expect.expect;
import com.googlecode.instinct.integrate.junit4.InstinctRunner;
import com.googlecode.instinct.marker.annotate.BeforeSpecification;
import com.googlecode.instinct.marker.annotate.Mock;
import com.googlecode.instinct.marker.annotate.Specification;
import com.googlecode.instinct.marker.annotate.Subject;


@RunWith(InstinctRunner.class)
public class LabelEditPresenterSpecs {
	@Subject private LabelEditPresenter SUT;
	
	@Mock private ILabelEditActivity labelEditActivity;
	@Mock private ILabelRepository labelRepository;
	
	@BeforeSpecification
	public void setUp() {
		SUT = new LabelEditPresenter(labelRepository);
	}
	
	@Specification
	void shouldSetEditModeOnActivity() {
		expect.that(new Expectations() {{
			oneOf(labelEditActivity).getTargetTitle(); will(returnValue("label 1"));
			oneOf(labelRepository).getLabelByTitle("label 1"); will(returnValue(new Label("label 1")));
			oneOf(labelEditActivity).setEdit("label 1");
		}});
		SUT.initializeWith(labelEditActivity);
	}
	
	@Specification
	void shouldSetNewModeOnActivityIfNoTargetLabel() {
		expect.that(new Expectations() {{
			oneOf(labelEditActivity).getTargetTitle(); will(returnValue(null));
			oneOf(labelEditActivity).setNew();
		}});
		SUT.initializeWith(labelEditActivity);
	}
	
	@Specification
	void shouldSaveEditedLabel() {
		expect.that(new Expectations() {{
			Label trgLabel = new Label("label 1");
			oneOf(labelEditActivity).getTargetTitle(); will(returnValue("label 1"));
			oneOf(labelRepository).getLabelByTitle("label 1"); will(returnValue(trgLabel));
			oneOf(labelEditActivity).setEdit("label 1");
			
			oneOf(labelEditActivity).getInputString(); will(returnValue("label 2"));
			oneOf(labelRepository).getLabelByTitle("label 2"); will(returnValue(null));
			oneOf(labelRepository).save(trgLabel);
			oneOf(labelEditActivity).exit();
		}});
		SUT.initializeWith(labelEditActivity);
		SUT.save();
	}
	
	@Specification
	void shouldSaveNewLabel() {
		expect.that(new Expectations() {{
			oneOf(labelEditActivity).getTargetTitle(); will(returnValue(null));
			oneOf(labelEditActivity).setNew();
			
			oneOf(labelEditActivity).getInputString(); will(returnValue("label 2"));
			oneOf(labelRepository).getLabelByTitle("label 2"); will(returnValue(null));
			oneOf(labelRepository).save(with(aLabelIdenticalWith(new Label("label 2"))));
			oneOf(labelEditActivity).exit();
		}});
		SUT.initializeWith(labelEditActivity);
		SUT.save();
	}
	
	@Specification
	void shouldDeleteLabel() {
		expect.that(new Expectations() {{
			oneOf(labelEditActivity).getTargetTitle(); will(returnValue("label 1"));
			oneOf(labelRepository).getLabelByTitle("label 1");
				will(returnValue(new Label("label 1")));
			oneOf(labelEditActivity).setEdit("label 1");
			
			oneOf(labelRepository).delete(with(aLabelIdenticalWith(new Label("label 1"))));
			oneOf(labelEditActivity).exit();
		}});
		SUT.initializeWith(labelEditActivity);
		SUT.delete();
	}
	
	@Specification
	void shouldExitIfDeleteInNewMode() {
		expect.that(new Expectations() {{
			oneOf(labelEditActivity).getTargetTitle(); will(returnValue(null));
			oneOf(labelEditActivity).setNew();
			
			oneOf(labelEditActivity).exit();
		}});
		SUT.initializeWith(labelEditActivity);
		SUT.delete();
	}
}
